package com.midongtech.cpd.utils;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;


import androidx.core.content.ContextCompat;

import com.midongtech.cpd.AppDownloadListener;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * created by HYW on 2019/6/26 0026
 * Describe:
 */
public class DownLoadApkManager {

    public static final String TAG = "DownLoadApkManager";

    private static volatile DownLoadApkManager downLoadApkManager;
    protected Context mContext;
    private String lastPath = "";
    private String mPackageName = "";
    private long currentTime;
    private List<String> downloadList = new ArrayList<>();
    private int lastProgress;
    private AppDownloadListener listener;
    private Map<String, HttpURLConnection> downloadMap = new HashMap<>();
    public String apkFilePath;

    private DownLoadApkManager(Context context, AppDownloadListener appDownloadListener) {
        mContext = context;
        listener = appDownloadListener;
    }

    public static DownLoadApkManager getInstance(Context context, AppDownloadListener appDownloadListener) {
        if (downLoadApkManager == null) {
            synchronized (DownLoadApkManager.class) {
                if (downLoadApkManager == null) {
                    downLoadApkManager = new DownLoadApkManager(context, appDownloadListener);
                }
            }
        }
        return downLoadApkManager;
    }


    public void startDownload(final String apkUrl, final String fileName, final String packageName, final String appid) {
        if (listener == null) {
            return;
        }
        Log.i(TAG, "apkUrl:" + apkUrl);
        final String filePath = new StringBuilder(ContextCompat.getExternalFilesDirs(
                mContext, null)[0].getAbsolutePath()).append(File.separator).append("Download").toString();
        File file2 = new File(filePath);
        if (!file2.exists() || !file2.isDirectory()) {
            file2.mkdirs();
        }
        final String apkFilePath = new StringBuilder(ContextCompat.getExternalFilesDirs(
                mContext, null)[0].getAbsolutePath()).append(File.separator).append("Download").append(File.separator).append(fileName).append(".apk").toString();
        if (!TextUtils.isEmpty(mPackageName) && mPackageName.equals(packageName)) {
            Log.i(TAG, "包名一致，不下载");
            if (new File(apkFilePath).exists() && AppUtils.isApkValid(apkFilePath, mContext)) {
                AppUtils.install(mContext, apkFilePath);
            } else {
                showToast("正在下载中，请稍后");
            }
            return;
        }
        if (downloadList.contains(apkUrl)) {
            showToast("正在下载中，请稍后");
            return;
        }
        if (new File(apkFilePath).exists()) {
            if (AppUtils.isApkValid(apkFilePath, mContext)) {
                AppUtils.install(mContext, apkFilePath);
                return;
            } else {
                new File(apkFilePath).delete();
            }
        }
        downloadList.add(apkUrl);
        lastPath = apkUrl;
        mPackageName = packageName;
        currentTime = System.currentTimeMillis();
        showToast("开始下载" + fileName + "，请稍候");
        new Thread(new Runnable() {
            @Override
            public void run() {
                int count = 0;
                try {
                    listener.onDownloadStart(appid, packageName);
                    URL url = new URL(apkUrl);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();//建立连接
                    connection.setConnectTimeout(15000);
                    connection.setReadTimeout(15000);
                    connection.setRequestProperty("User-agent", DeviceUtil.getUserAgent(mContext));
                    connection.setRequestMethod("GET");
                    downloadMap.put(packageName, connection);
                    connection.setInstanceFollowRedirects(false);
                    Log.i(TAG, "connection.getResponseCode():" + connection.getResponseCode() + "   url:" + apkUrl);
                    if (connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM || connection.getResponseCode() == 307) {
                        connection = redirectUrl(connection);
                        if (connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_TEMP || connection.getResponseCode() == HttpURLConnection.HTTP_MOVED_PERM || connection.getResponseCode() == 307) {
                            connection = redirectUrl(connection);
                        }
                    }

                    int totalSize = connection.getContentLength();//获取文件总大小

                    Log.i(TAG, "apkFilePath:" + apkFilePath);

                    InputStream is = connection.getInputStream();
                    OutputStream os = new FileOutputStream(
                            apkFilePath);
                    int len = 0;
                    byte bs[] = new byte[1024];
                    while ((len = is.read(bs)) != -1) {
                        os.write(bs, 0, len);//写入文件
                        count += len;
                        final int count2 = (int) (count * 100.0 / totalSize);
                        if (lastProgress < count2) {
                            if (packageName.equals(mPackageName)) {
                                listener.onProgressUpdate(appid, mPackageName, count2);
                            }
                        }
                        lastProgress = (int) (count * 100.0 / totalSize);
                        if (lastProgress == 100) {
                            AppUtils.install(mContext, apkFilePath);
                            listener.onDownloadSuccess(appid, packageName);
                        }
                    }

                    lastPath = "";
                    downloadList.remove(apkUrl);
                    mPackageName = "";
                    downloadMap.remove(packageName);
                    os.flush();
                    is.close();
                    os.close();
                } catch (Exception e) {
                    e.printStackTrace();
                    lastPath = "";
                    downloadList.remove(apkUrl);
                    listener.onDownloadFail(appid, packageName);
                    mPackageName = "";
                    downloadMap.remove(packageName);
                    Log.e("hyw", "HttpURLConnection.Exception:" + e.getMessage());
                }
            }
        }).start();

    }

    private HttpURLConnection redirectUrl(HttpURLConnection connection) {
        try {
            connection.disconnect();
            String location2 = connection.getHeaderField("Location");
            Log.i(TAG, "location2:" + location2);
            connection = (HttpURLConnection) new URL(location2).openConnection();
            connection.setRequestProperty("User-agent", DeviceUtil.getUserAgent(mContext));
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(15000);
            connection.setReadTimeout(15000);
            Log.i(TAG, "connection.getResponseCode()3:" + connection.getResponseCode());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }


    public void cancelDownload() {
        Log.i(TAG, "清空下载队列");
        try {
            Iterator it = downloadMap.values().iterator();
            while (it.hasNext()) {
                HttpURLConnection connection = (HttpURLConnection) it.next();
                connection.disconnect();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        lastPath = "";
        downloadList.clear();
        mPackageName = "";
    }

    private void showToast(final String text) {
        new Handler(mContext.getMainLooper()).post(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(mContext, text, Toast.LENGTH_LONG).show();
            }
        });
    }

}
